﻿using System;
using System.IO;
using System.Text;
using System.Threading;
using Nb.Common;
using Nb.Common.MachineCodes;

namespace Nb.Tools.MachineCodeTracker
{
    /// <summary>
    /// 读取目标服务器上的机器码，如果发生变化，则写入log.txt文件
    /// </summary>
    public static class MachineCodeWatcher
    {
        private static readonly StringBuilder sb = new StringBuilder();
        static MachineCodeWatcher()
        {
            UtilsLogger.SetLogFunc(WriteLog);
        }

        private static readonly object mylock = new object();
        private static bool _running = false;
        private static int _runningSpan = 3000;
        private static Thread _worker = null;
        private static string _filePath = null;

        /// <summary>
        /// 要写入的文件的名称，不包含路径
        /// </summary>
        public static string LogFileName = "log.txt";

        public static void Start(int span = 3000)
        {
            lock (mylock)
            {
                _runningSpan = span;
                string folderPath = MyIOHelper.GetExecutingAssemblyFolderPath();
                _filePath = MyIOHelper.MakeSubFolderPath(folderPath, LogFileName);

                _running = true;
                if (_worker == null)
                {
                    _worker = new Thread(Work);
                    _worker.IsBackground = true;
                }
                
                PrintAndRecord(true);
                _worker.Start();

            }
        }

        public static void Stop()
        {
            lock (mylock)
            {
                _running = false;
                _worker = null;
            }
        }

        private static string _lastReadCode = null;
        private static void Work()
        {
            while (_running)
            {
                PrintAndRecord();
                Thread.Sleep(_runningSpan);
            }
        }

        private static void PrintAndRecord(bool alwaysWriteFile = false)
        {
            sb.Clear();
            bool writeFile = false;

            string readCode = MachineCodeFacade.ReadCode();
            string message = string.Format("读到机器码：{0}, {1}", readCode, DateTime.Now);
            sb.AppendLine(message);

            if (!string.IsNullOrWhiteSpace(_lastReadCode) && _lastReadCode != readCode)
            {
                sb.AppendLine("==================");
                string changeMessage = string.Format("机器码改变！！！ {0} => {1}", _lastReadCode, readCode);
                sb.AppendLine("==================");
                sb.AppendLine(changeMessage);
                writeFile = true;
            }

            _lastReadCode = readCode;
            sb.AppendLine("------------------------------------------------");

            Console.WriteLine(sb);
            if (alwaysWriteFile || writeFile)
            {
                try
                {
                    File.AppendAllText(_filePath, string.Format("{0} \r\n", sb.ToString()));
                }
                catch (Exception)
                {
                    //发生了IO异常，终止程序
                    _running = false;
                    _worker = null;
                    throw;
                }

            }
        }

        static void WriteLog(string message)
        {
            sb.AppendLine(message);
        }
    }
}
